﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MulticastTV
{
    /// <summary>
    /// Osd layed window . obsolete
    /// </summary>
    public partial class OsdWindow : Form
    {
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        static extern bool SetWindowPos(
             int hWnd,           // window handle
             int hWndInsertAfter,    // placement-order handle
             int X,          // horizontal position
             int Y,          // vertical position
             int cx,         // width
             int cy,         // height
             uint uFlags);       // window positioning flags

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int HWND_TOPMOST = -1;
        private const uint SWP_NOACTIVATE = 0x0010;
        private const int SW_SHOWNA = 8;
        public const uint WS_POPUP = 0x80000000;
        public const int WS_EX_TOPMOST = 0x8;
        public const int WS_EX_TOOLWINDOW = 0x80;
        public const int WS_EX_LAYERED = 0x80000;
        public const int WS_EX_TRANSPARENT = 0x20;
        public const int WS_EX_NOACTIVATE = 0x08000000;
        public const int SW_SHOWNOACTIVATE = 4;
        public const int SW_HIDE = 0;
        public const uint AW_HOR_POSITIVE = 0x1;
        public const uint AW_HOR_NEGATIVE = 0x2;
        public const uint AW_VER_POSITIVE = 0x4;
        public const uint AW_VER_NEGATIVE = 0x8;
        public const uint AW_CENTER = 0x10;
        public const uint AW_HIDE = 0x10000;
        public const uint AW_ACTIVATE = 0x20000;
        public const uint AW_SLIDE = 0x40000;
        public const uint AW_BLEND = 0x80000;

        Font font =new Font("Verdana", 22, FontStyle.Bold);
        Color color = Properties.Settings.Default.OSDcolor;
        volatile string input ="";
        string align ="";
        int opacity = 100;
        static int xoffset = 25;
        static int yoffset = 25;

        StringFormat stringFormat;
        StringFormat stringFormat2;
        Form1 parent;
        Timer ThideOsd = new Timer();

        public OsdWindow( Form1 pr)
        {
            InitializeComponent();
            parent = pr;
            //this.BackColor = Color.FromArgb(0, 0, 1);
            //if (Properties.Settings.Default.OsdTransparentBackgroundV2 == 1)
            //    this.TransparencyKey = this.BackColor;
            //else
            //    this.TransparencyKey = Color.Empty;

            //left
            stringFormat2 = new StringFormat();
            stringFormat2.Alignment = StringAlignment.Near;
            stringFormat2.LineAlignment = StringAlignment.Center;
            //stringFormat2.FormatFlags = StringFormatFlags.LineLimit;
            //stringFormat2.Trimming = StringTrimming.EllipsisCharacter;
            
            //right
            stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Far;
            stringFormat.LineAlignment = StringAlignment.Center;
            // stringFormat.Trimming = StringTrimming.EllipsisCharacter;

            ThideOsd.Interval = 1500;
            ThideOsd.Tick += new EventHandler(ThideOsd_Tick);
        }

        //protected override CreateParams CreateParams
        //{
        //    get
        //    {
        //        CreateParams createParams = base.CreateParams;
              
        //        if (Properties.Settings.Default.OsdTransparentBackgroundV2 == 1)
        //            createParams.ExStyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT;
        //       // else
        //          //  createParams.ExStyle = WS_EX_TOPMOST | WS_EX_NOACTIVATE | WS_EX_TRANSPARENT;

        //        return createParams;
        //    }
        //}

        private void OsdWindow_Paint(object sender, PaintEventArgs e)
        {
           Graphics g = e.Graphics;
           g.SmoothingMode = SmoothingMode.HighQuality;
           g.InterpolationMode = InterpolationMode.HighQualityBilinear;
           g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

            int width = e.ClipRectangle.Width;
            int height = e.ClipRectangle.Height;
            int test1 = this.Width;
            int test2 = this.Height;
            if (test1 != 0 && test2 != 0 && width != 0 && height != 0)
            {
                int BlurAmt = 2;
                Rectangle rect = new Rectangle(BlurAmt, BlurAmt, Math.Max(1,width - BlurAmt), Math.Max(1,height - BlurAmt));
                Rectangle rectBlur = new Rectangle(0, 0, width , height);
                if (align == "left")
                {
                   // black outline
                    for (int x = 0; x <= BlurAmt; x++)
                    {
                        rectBlur.X = x;
                        for (int y = 0; y <= BlurAmt; y++)
                        {
                            rectBlur.Y = y;
                            e.Graphics.DrawString(input, font, new SolidBrush(Color.Black), rectBlur, stringFormat2);
                        }
                    }
                    
                    //channel ar, crop, rate ...
                    e.Graphics.DrawString(input, font, new SolidBrush(color), rect, stringFormat2);
                }
                else if (align == "right")
                //volume
                {
                    e.Graphics.DrawString("llllllllll", font, Brushes.Gray, rect, stringFormat2);
                    e.Graphics.DrawString(input, font, new SolidBrush(color), rect, stringFormat2);
                }
            }
        }

        /// <summary>
        /// Show OSD
        /// </summary>
        /// <param name="text">Text to show</param>
        /// <param name="edge">Align</param>
        /// <param name="f">Font</param>
        /// <param name="c">Font color</param>
        /// <param name="size">Text size</param>
        /// <param name="alpha">Alpha</param>
        /// <param name="timeout">Timeout</param>
        /// <param name="xofs">X offset</param>
        /// <param name="yxofs">Y offset</param> 
        public void Start(string text, string edge, Font f,Color c, int size, int alpha, int timeout, int xofs, int yofs)
        {
            if (this.Size == new Size(0, 0))
                return;
            
            this.StartPosition = FormStartPosition.Manual;
            input = text;
            align = edge;
            font = f;
            font = ChangeFontSize(font, size);
            opacity = alpha;
            xoffset = xofs;
            yoffset = yofs;
            color = c;
            ThideOsd.Stop();
            ThideOsd.Interval = timeout;
            ThideOsd.Start();
            this.Invalidate(this.ClientRectangle);
            this.Update();
           
            showWindow();
        }

        private void showWindow()
        {
            if (this.Visible && align !="right")
                hideWindow();
            
            int width = parent.Width;
            //calculate height from font size
            float ascentpx;
            float descentpx;
            ascentpx = font.Size * font.FontFamily.GetCellAscent(font.Style) / font.FontFamily.GetEmHeight(font.Style);
            descentpx = font.Size * font.FontFamily.GetCellDescent(font.Style) / font.FontFamily.GetEmHeight(font.Style);

            int height = (int)(Math.Round((descentpx * 3) + ascentpx));

            int stringlength;
            if (align == "right")
                stringlength = TextRenderer.MeasureText("llllllllll" + "l", font).Width;
            else
                stringlength = TextRenderer.MeasureText(input+"l", font).Width;

            SetWindowPos(this.Handle.ToInt32(), HWND_TOPMOST,
            parent.Location.X + xoffset, parent.Location.Y + yoffset, Math.Max(1, Math.Min(width - xoffset, stringlength + 2)), Math.Max(1, height),
            SWP_NOACTIVATE);

            if (!this.Visible)
                ShowWindow(this.Handle, SW_SHOWNOACTIVATE);

            if (this.Focused)
                parent.pictureBox1.Focus();
        }

        public void hideWindow()
        {
            ShowWindow(this.Handle, SW_HIDE);
        }

        private void ThideOsd_Tick(object sender, EventArgs e)
        {
            hideWindow();
            ThideOsd.Stop();
        }

        static public Font ChangeFontSize(Font font, float fontSize)
        {
            if (font != null)
            {
                float currentSize = font.Size;
                if (currentSize != fontSize)
                {
                    font = new Font(font.Name, fontSize,
                        font.Style, font.Unit,
                        font.GdiCharSet, font.GdiVerticalFont);
                }
            }
            return font;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        protected override void WndProc(ref Message m)
        {
              //remote controll
            if (m.Msg == 0x8888 && Properties.Settings.Default.RemoteMode2)
            { 
               //repost to parent
                PostMessage(parent.Handle,m.Msg,(int)m.WParam, (int)m.LParam);
                m.Result = new IntPtr(0);
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        public string  getText()
        {
            return input; 
        }
    }
}
